#!/bin/bash
set -e

# 颜色定义
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[1;34m'
NC='\033[0m'

# 日志文件路径
LOG_FILE="/var/log/ssl-auto.log"

# 默认值
CA="letsencrypt"
VALIDATION="dns"
DOMAIN=""
TYPE="single"
CSR_KEY=""
CSR_CSR=""
CRON_ADD=false
SAN_DOMAINS=()
KEY_TYPE="rsa"     # rsa or ec
KEY_BITS=2048      # for RSA
ECC_CURVE="prime256v1"  # for EC
TMP_DIR="/tmp/acme-csr"
CERT_DIR="/etc/nginx/ssl"

# DNS API 凭据
ALI_KEY=""
ALI_SECRET=""
TENCENT_SECRET_ID=""
TENCENT_SECRET_KEY=""
CF_API_KEY=""
CF_ZONE_ID=""
DP_Id=""
DP_Key=""

usage() {
    echo -e "${YELLOW}这是一个交互式 SSL 证书申请脚本。请根据提示输入所需信息。${NC}"
}

log() {
    echo "$(date '+%Y-%m-%d %H:%M:%S') $*" >> "$LOG_FILE"
}

detect_os() {
    if [[ "$OSTYPE" == "linux-gnu"* ]]; then
        OS="linux"
    elif [[ "$OSTYPE" == "darwin"* ]]; then
        OS="macos"
    else
        log "⚠️ 不支持的操作系统: $OSTYPE"
        echo "❌ 不支持的操作系统: $OSTYPE"
        exit 1
    fi
}

list_nginx_sites() {
    echo -e "${YELLOW}🔍 当前服务器上已启用的网站域名：${NC}"
    SITES=$(find /etc/nginx/sites-enabled/ -type f -exec grep -h 'server_name' {} \; | awk '{print $2}' | sed 's/;//')
    if [ -z "$SITES" ]; then
        echo "⚠️ 未找到任何已启用的站点"
    else
        echo "$SITES"
    fi
    echo ""
}

input_domain() {
    list_nginx_sites
    read -p "请输入主域名 (例如 example.com): " DOMAIN
    if [ -z "$DOMAIN" ]; then
        echo "❌ 域名不能为空，请重新输入"
        input_domain
    fi
}

select_type() {
    echo -e "${YELLOW}请选择证书类型:${NC}"
    echo "1) 单域名 (example.com)"
    echo "2) 通配符域名 (*.example.com)"
    echo "3) SAN 多域名 (example.com + 其他域名)"
    read -p "请输入编号 (1/2/3): " type_choice
    case "$type_choice" in
        1)
            TYPE="single"
            SAN_DOMAINS=()
            ;;
        2)
            TYPE="wildcard"
            SAN_DOMAINS=()
            ;;
        3)
            TYPE="san"
            read -p "请输入附加的 SAN 域名，多个用空格分隔 (如 www.example.com blog.example.com): " -a SAN_DOMAINS
            ;;
        *)
            echo "❌ 无效的选择，请重新输入"
            select_type
            ;;
    esac
}

select_validation() {
    echo -e "${YELLOW}请选择验证方式:${NC}"
    echo "1) DNS 验证 (推荐用于泛解析)"
    echo "2) Webroot 验证"
    read -p "请输入编号 (1/2): " val_choice
    case "$val_choice" in
        1)
            VALIDATION="dns"
            echo -e "${YELLOW}请选择DNS服务提供商:${NC}"
            echo "1) 腾讯云"
            echo "2) 阿里云"
            echo "3) Cloudflare"
            echo "4) 百度云"
            echo "5) 华为云"
            read -p "请输入编号 (1-5): " dns_provider
            case "$dns_provider" in
                1)
                    read -p "请输入腾讯云 SecretId: " TENCENT_SECRET_ID
                    read -s -p "请输入腾讯云 SecretKey: " TENCENT_SECRET_KEY
                    export TENCENT_SECRET_ID="$TENCENT_SECRET_ID"
                    export TENCENT_SECRET_KEY="$TENCENT_SECRET_KEY"
                    ;;
                2)
                    read -p "请输入阿里云 AccessKeyId: " ALI_ACCESS_KEY_ID
                    read -s -p "请输入阿里云 AccessKeySecret: " ALI_ACCESS_KEY_SECRET
                    export Ali_Key="$ALI_ACCESS_KEY_ID"
                    export Ali_Secret="$ALI_ACCESS_KEY_SECRET"
                    ;;
                3)
                    read -p "请输入 Cloudflare API Key: " CF_API_KEY
                    read -p "请输入 Cloudflare Zone ID: " CF_ZONE_ID
                    export CF_Key="$CF_API_KEY"
                    export CF_Zone_Id="$CF_ZONE_ID"
                    ;;
                4)
                    read -p "请输入百度云 Access Key ID: " BAIDU_ACCESS_KEY_ID
                    read -s -p "请输入百度云 Secret Access Key: " BAIDU_SECRET_ACCESS_KEY
                    export BAIDU_ACCESS_KEY_ID="$BAIDU_ACCESS_KEY_ID"
                    export BAIDU_SECRET_ACCESS_KEY="$BAIDU_SECRET_ACCESS_KEY"
                    ;;
                5)
                    read -p "请输入华为云 Access Key ID: " HW_ACCESS_KEY_ID
                    read -s -p "请输入华为云 Secret Access Key: " HW_SECRET_ACCESS_KEY
                    export HW_ACCESS_KEY_ID="$HW_ACCESS_KEY_ID"
                    export HW_SECRET_ACCESS_KEY="$HW_SECRET_ACCESS_KEY"
                    ;;
                *)
                    echo "❌ 无效的选择，默认使用阿里云"
                    read -p "请输入阿里云 AccessKeyId: " ALI_ACCESS_KEY_ID
                    read -s -p "请输入阿里云 AccessKeySecret: " ALI_ACCESS_KEY_SECRET
                    export Ali_Key="$ALI_ACCESS_KEY_ID"
                    export Ali_Secret="$ALI_ACCESS_KEY_SECRET"
                    ;;
            esac
            ;;
        2)
            VALIDATION="webroot"
            ;;
        *)
            echo "❌ 无效的选择，请重新输入"
            select_validation
            ;;
    esac
}

select_ca() {
    echo -e "${YELLOW}请选择证书颁发机构 (CA):${NC}"
    echo "1) Let's Encrypt (默认)"
    echo "2) ZeroSSL"
    echo "3) Buypass"
    read -p "请输入编号 (1/2/3): " ca_choice
    case "$ca_choice" in
        1) CA="letsencrypt" ;;
        2) CA="zerossl" ;;
        3) CA="buypass" ;;
        *) echo "❌ 无效的选择，默认使用 Let's Encrypt"; CA="letsencrypt" ;;
    esac
}

select_key_type() {
    echo -e "${YELLOW}请选择私钥类型:${NC}"
    echo "1) RSA (2048位)"
    echo "2) ECC (prime256v1)"
    read -p "请输入编号 (1/2): " key_choice
    case "$key_choice" in
        1) KEY_TYPE="rsa" ;;
        2) KEY_TYPE="ec" ;;
        *) echo "❌ 无效的选择，默认使用 RSA"; KEY_TYPE="rsa" ;;
    esac
}

input_email() {
    read -p "请输入你的邮箱地址（用于证书通知，可留空）: " EMAIL
}

enable_cron() {
    read -p "是否自动添加每日续期任务到 crontab? (y/n): " cron_choice
    case "$cron_choice" in
        y|Y) CRON_ADD=true ;;
        n|N) CRON_ADD=false ;;
        *) echo "❌ 无效输入，默认不添加"; CRON_ADD=false ;;
    esac
}

show_summary() {
    echo -e "\n${GREEN}✅ 当前配置摘要:${NC}"
    echo "主域名:      $DOMAIN"
    echo "证书类型:    $TYPE"
    if [ "$TYPE" == "san" ] && [ ${#SAN_DOMAINS[@]} -gt 0 ]; then
        echo "SAN 域名:   ${SAN_DOMAINS[*]}"
    fi
    echo "验证方式:    $VALIDATION"
    echo "DNS 提供商:  $(get_dns_provider_name)"
    echo "CA:          $CA"
    echo "私钥类型:    $KEY_TYPE"
    echo "自动续期:    $(if $CRON_ADD; then echo "是"; else echo "否"; fi)"
    echo
}

get_dns_provider_name() {
    if [[ -n "$TENCENT_SECRET_ID" ]]; then echo "腾讯云"
    elif [[ -n "$Ali_Key" ]]; then echo "阿里云"
    elif [[ -n "$CF_API_KEY" ]]; then echo "Cloudflare"
    elif [[ -n "$DP_Id" ]]; then echo "DNSPod"
    else echo "未知"
    fi
}

generate_csr_and_key() {
    mkdir -p "$TMP_DIR"
    CSR_KEY="$TMP_DIR/privkey.pem"
    CSR_CSR="$TMP_DIR/csr.pem"

    echo -e "${BLUE}请选择 CSR 生成方式:${NC}"
    echo "1) 自动生成 CSR 和私钥（推荐）"
    echo "2) 使用自定义 CSR 和私钥"
    read -p "请输入编号 (1/2): " csr_choice

    case "$csr_choice" in
        1)
            echo -e "${BLUE}生成私钥和 CSR...${NC}"

            if [ "$KEY_TYPE" == "rsa" ]; then
                openssl genrsa -out "$CSR_KEY" $KEY_BITS
            elif [ "$KEY_TYPE" == "ec" ]; then
                openssl ecparam -name "$ECC_CURVE" -genkey -out "$CSR_KEY"
            fi

            SAN_ENTRIES=("DNS.1 = $DOMAIN")
            index=2
            if [ "$TYPE" == "wildcard" ]; then
                SAN_ENTRIES+=("DNS.2 = *.$DOMAIN")
            elif [ "$TYPE" == "san" ]; then
                for domain in "${SAN_DOMAINS[@]}"; do
                    SAN_ENTRIES+=("DNS.$index = $domain")
                    ((index++))
                done
            fi

            cat > "$TMP_DIR/openssl.cnf" <<EOF
[ req ]
default_bits       = 2048
prompt             = no
default_md         = sha256
req_extensions     = req_ext
distinguished_name = dn

[ dn ]
CN                 = $DOMAIN

[ req_ext ]
subjectAltName     = @alt_names

[ alt_names ]
$(printf "%s\n" "${SAN_ENTRIES[@]}")
EOF

            openssl req -new -key "$CSR_KEY" -out "$CSR_CSR" -config "$TMP_DIR/openssl.cnf"
            echo -e "${GREEN}✅ 已生成私钥和 CSR：$CSR_KEY 和 $CSR_CSR${NC}"
            ;;
        2)
            read -p "请输入自定义私钥文件路径（如 /path/to/privkey.pem）: " CSR_KEY
            read -p "请输入自定义 CSR 文件路径（如 /path/to/csr.pem）: " CSR_CSR

            if [ ! -f "$CSR_KEY" ]; then
                echo "❌ 私钥文件不存在: $CSR_KEY"
                exit 1
            fi

            if [ ! -f "$CSR_CSR" ]; then
                echo "❌ CSR 文件不存在: $CSR_CSR"
                exit 1
            fi

            echo -e "${GREEN}✅ 已使用自定义私钥和 CSR：$CSR_KEY 和 $CSR_CSR${NC}"
            ;;
        *)
            echo "❌ 无效的选择，默认使用自动生成 CSR"
            generate_csr_and_key
            return
            ;;
    esac
}

run_acme_issue() {
    echo -e "${BLUE}开始签发证书...${NC}"

    ACME_INSTALL_DIR="$HOME/.acme.sh"
    ACME_CMD="$ACME_INSTALL_DIR/acme.sh"

    if [ ! -d "$ACME_INSTALL_DIR" ]; then
        echo -e "${GREEN}正在从国内镜像安装 acme.sh...${NC}"
        cd /tmp || exit 1
        curl -sO https://gitee.com/neilpang/acme.sh/raw/master/acme.sh
        chmod +x acme.sh
        ./acme.sh --install --home "$HOME/.acme.sh" ${EMAIL:+--accountemail "$EMAIL"}
        source ~/.bashrc || source ~/.zshrc
    fi

    case "$CA" in
        letsencrypt) CA="--server letsencrypt";;
        zerossl) CA="--server zerossl";;
        buypass) CA="--server buypass";;
    esac

    if [ ! -f "$ACME_INSTALL_DIR/account.conf" ]; then
        echo "⚠️ 检测到首次运行，正在注册账户..."
        "$ACME_CMD" --register-account $CA
    fi

    CMD=("$ACME_CMD" --force --issue $CA)

    for domain in "${SAN_DOMAINS[@]}" "$DOMAIN"; do
        CMD+=("-d" "$domain")
    done

    if [ "$VALIDATION" == "dns" ]; then
        if [[ -n "$TENCENT_SECRET_ID" ]]; then
            CMD+=("--dns" "dns_tencent")
        elif [[ -n "$Ali_Key" ]]; then
            CMD+=("--dns" "dns_ali")
        elif [[ -n "$CF_API_KEY" ]]; then
            CMD+=("--dns" "dns_cf")
        elif [[ -n "$BAIDU_ACCESS_KEY_ID" ]]; then
            CMD+=("--dns" "dns_baidu")
        elif [[ -n "$HW_ACCESS_KEY_ID" ]]; then
            CMD+=("--dns" "dns_huawei") # 注意：需要确认是否存在此插件或需自定义实现
        fi
    else
        CMD+=("--webroot" "/usr/share/nginx/html")
    fi

    "${CMD[@]}"

    CERT_PATH="$CERT_DIR/$DOMAIN"
    mkdir -p "$CERT_PATH"

    "$ACME_CMD" --install-cert \
                -d "$DOMAIN" \
                ${SAN_DOMAINS[*]/#/-d } \
                --key-file "$CERT_PATH/privkey.pem" \
                --fullchain-file "$CERT_PATH/fullchain.cer" \
                --reloadcmd "systemctl reload nginx"

    echo -e "${GREEN}✅ 证书已成功签发并部署！路径: $CERT_PATH${NC}"

    if [ "$CRON_ADD" = true ]; then
        (crontab -l 2>/dev/null; echo "0 0 * * * $ACME_CMD --cron > /dev/null") | crontab -
        echo -e "${GREEN}⏰ 已添加每日自动续期任务到 crontab${NC}"
    fi

    systemctl reload nginx
    echo -e "${GREEN}Nginx 服务已重载${NC}"
}

configure_nginx() {
    echo -e "${BLUE}配置 Nginx HTTPS...${NC}"
    SITE_CONF="/etc/nginx/sites-available/${DOMAIN}.conf"
    BACKUP_CONF="${SITE_CONF}.bak"

    if [ -f "$SITE_CONF" ]; then
        cp "$SITE_CONF" "$BACKUP_CONF"
        echo -e "${GREEN}已备份现有配置文件至: $BACKUP_CONF${NC}"
    fi

    cat > "$SITE_CONF" <<EOF
server {
    listen 80;
    server_name $DOMAIN ${SAN_DOMAINS[*]};

    location /.well-known/acme-challenge/ {
        root /usr/share/nginx/html;
    }

    location / {
        return 301 https://\$host\$request_uri;
    }
}

server {
    listen 443 ssl;
    server_name $DOMAIN ${SAN_DOMAINS[*]};

    ssl_certificate $CERT_DIR/$DOMAIN/fullchain.cer;
    ssl_certificate_key $CERT_DIR/$DOMAIN/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;

    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
    }
}
EOF

    ln -sf "$SITE_CONF" /etc/nginx/sites-enabled/
    echo -e "${GREEN}✅ Nginx 已配置为使用 HTTPS，路径: $SITE_CONF${NC}"
}

main() {
    usage
    detect_os
    input_domain
    select_type
    select_validation
    select_ca
    select_key_type
    input_email
    enable_cron
    show_summary

    read -p "确认以上配置并继续? (y/n): " confirm
    if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
        echo "操作已取消。"
        exit 0
    fi

    log "Starting SSL setup for domain: $DOMAIN"
    generate_csr_and_key
    run_acme_issue
    configure_nginx
    log "SSL setup completed successfully."
}

main